package ldh.im.fxbase.virtualFlow.utils;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

public class NumberUtils {
    private NumberUtils() {
    }

    public static double clamp(double val, double min, double max) {
        return Math.max(min, Math.min(max, val));
    }

    public static float clamp(float val, float min, float max) {
        return Math.max(min, Math.min(max, val));
    }

    public static int clamp(int val, int min, int max) {
        return Math.max(min, Math.min(max, val));
    }

    public static long clamp(long val, long min, long max) {
        return Math.max(min, Math.min(max, val));
    }

    public static double closestValueTo(double val, List<Double> list) {
        if (list.isEmpty()) {
            return 0.0D;
        } else {
            double res = (Double)list.get(0);

            for(int i = 1; i < list.size(); ++i) {
                if (Math.abs(val - res) > Math.abs(val - (Double)list.get(i))) {
                    res = (Double)list.get(i);
                }
            }

            return res;
        }
    }

    public static float closestValueTo(float val, List<Float> list) {
        if (list.isEmpty()) {
            return 0.0F;
        } else {
            float res = (Float)list.get(0);

            for(int i = 1; i < list.size(); ++i) {
                if (Math.abs(val - res) > Math.abs(val - (Float)list.get(i))) {
                    res = (Float)list.get(i);
                }
            }

            return res;
        }
    }

    public static int closestValueTo(int val, List<Integer> list) {
        if (list.isEmpty()) {
            return 0;
        } else {
            int res = (Integer)list.get(0);

            for(int i = 1; i < list.size(); ++i) {
                if (Math.abs(val - res) > Math.abs(val - (Integer)list.get(i))) {
                    res = (Integer)list.get(i);
                }
            }

            return res;
        }
    }

    public static long closestValueTo(long val, List<Long> list) {
        if (list.isEmpty()) {
            return 0L;
        } else {
            long res = (Long)list.get(0);

            for(int i = 1; i < list.size(); ++i) {
                if (Math.abs(val - res) > Math.abs(val - (Long)list.get(i))) {
                    res = (Long)list.get(i);
                }
            }

            return res;
        }
    }

    public static double formatTo(double value, int decimalPrecision) {
        int calcScale = (int)Math.pow(10.0D, (double)decimalPrecision);
        return (double)Math.round(value * (double)calcScale) / (double)calcScale;
    }

    public static String formatToString(double value, int decimalPrecision) {
        return String.format("%." + decimalPrecision + "f", value);
    }

    public static double getRandomDoubleBetween(double min, double max) {
        return ThreadLocalRandom.current().nextDouble(min, max);
    }

    public static float getRandomFloat() {
        return ThreadLocalRandom.current().nextFloat();
    }

    public static int getRandomIntBetween(int min, int max) {
        return ThreadLocalRandom.current().nextInt(min, max);
    }

    public static long getRandomLongBetween(long min, long max) {
        return ThreadLocalRandom.current().nextLong(min, max);
    }

    public static boolean isEven(int number) {
        return number % 2 == 0;
    }
}
